Completed
Push — master ( 053a36...0a386d )
by Sander
03:38
created

angular.controller(ꞌCredentialCtrlꞌ)   C

Complexity

Conditions 8
Paths 16

Size

Total Lines 410

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
nc 16
nop 19
dl 0
loc 410
rs 5.2676
c 1
b 0
f 0

How to fix   Long Method    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
/**
2
 * Nextcloud - passman
3
 *
4
 * @copyright Copyright (c) 2016, Sander Brand ([email protected])
5
 * @copyright Copyright (c) 2016, Marcos Zuriaga Miguel ([email protected])
6
 * @license GNU AGPL version 3 or any later version
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License as
10
 * published by the Free Software Foundation, either version 3 of the
11
 * License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU Affero General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Affero General Public License
19
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 *
21
 */
22
23
(function () {
24
	'use strict';
25
26
27
	/**
28
	 * @ngdoc function
29
	 * @name passmanApp.controller:MainCtrl
30
	 * @description
31
	 * # MainCtrl
32
	 * Controller of the passmanApp
33
	 */
34
	angular.module('passmanApp')
35
		.controller('CredentialCtrl', ['$scope', 'VaultService', 'SettingsService', '$location', 'CredentialService',
36
			'$rootScope', 'FileService', 'EncryptService', 'TagService', '$timeout', 'NotificationService', 'CacheService', 'ShareService', 'SharingACL', '$interval', '$filter', '$routeParams', '$sce', '$translate',
37
			function ($scope, VaultService, SettingsService, $location, CredentialService, $rootScope, FileService, EncryptService, TagService, $timeout, NotificationService, CacheService, ShareService, SharingACL, $interval, $filter, $routeParams, $sce, $translate) {
38
				$scope.active_vault = VaultService.getActiveVault();
39
				if (!SettingsService.getSetting('defaultVault') || !SettingsService.getSetting('defaultVaultPass')) {
40
					if (!$scope.active_vault) {
41
						$location.path('/');
42
					}
43
				} else {
44
					if (SettingsService.getSetting('defaultVault') && SettingsService.getSetting('defaultVaultPass')) {
45
						var _vault = angular.copy(SettingsService.getSetting('defaultVault'));
46
						_vault.vaultKey = angular.copy(SettingsService.getSetting('defaultVaultPass'));
47
						VaultService.setActiveVault(_vault);
48
						$scope.active_vault = _vault;
49
						//@TODO check if vault exists
50
					}
51
				}
52
53
				$scope.show_spinner = true;
54
				var fetchCredentials = function () {
55
					VaultService.getVault({guid: $routeParams.vault_id}).then(function (vault) {
56
						var vaultKey = angular.copy($scope.active_vault.vaultKey);
57
						var _credentials = angular.copy(vault.credentials);
58
						vault.credentials = [];
59
						$scope.active_vault = vault;
60
						$scope.active_vault.vaultKey = vaultKey;
61
						VaultService.setActiveVault($scope.active_vault);
62
						for (var i = 0; i < _credentials.length; i++) {
63
							var _credential = _credentials[i];
64
							try {
65
								if (!_credential.shared_key) {
66
									_credential = CredentialService.decryptCredential(angular.copy(_credential));
67
68
								} else {
69
									var enc_key = EncryptService.decryptString(_credential.shared_key);
70
									_credential = ShareService.decryptSharedCredential(angular.copy(_credential), enc_key);
71
								}
72
								_credential.tags_raw = _credential.tags;
73
							} catch (e) {
74
75
								NotificationService.showNotification($translate.instant('error.decrypt'), 5000);
76
								//$rootScope.$broadcast('logout');
77
								//SettingsService.setSetting('defaultVaultPass', null);
78
								//.setSetting('defaultVault', null);
79
								//$location.path('/')
80
81
							}
82
							_credentials[i] = _credential;
83
						}
84
85
						ShareService.getCredendialsSharedWithUs(vault.guid).then(function (shared_credentials) {
86
							for (var c = 0; c < shared_credentials.length; c++) {
87
								var _shared_credential = shared_credentials[c];
88
								var decrypted_key = EncryptService.decryptString(_shared_credential.shared_key);
89
								var _shared_credential_data;
90
								try {
91
									_shared_credential_data = ShareService.decryptSharedCredential(_shared_credential.credential_data, decrypted_key);
92
								} catch (e) {
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
93
94
								}
95
								if (_shared_credential_data) {
96
									delete _shared_credential.credential_data;
97
									_shared_credential_data.acl = _shared_credential;
98
									_shared_credential_data.acl.permissions = new SharingACL(_shared_credential_data.acl.permissions);
99
									_shared_credential_data.tags_raw = _shared_credential_data.tags;
100
									_credentials.push(_shared_credential_data);
101
								}
102
							}
103
							angular.merge($scope.active_vault.credentials, _credentials);
104
							$scope.show_spinner = false;
105
106
							if(!vault.private_sharing_key){
107
								var key_size = 1024;
108
								ShareService.generateRSAKeys(key_size).then(function (kp) {
109
									var pem = ShareService.rsaKeyPairToPEM(kp);
110
									$scope.creating_keys = false;
111
									$scope.active_vault.private_sharing_key = pem.privateKey;
112
									$scope.active_vault.public_sharing_key = pem.publicKey;
113
									$scope.$digest();
114
									VaultService.updateSharingKeys($scope.active_vault);
115
								});
116
							}
117
						});
118
					});
119
				};
120
121
				var getPendingShareRequests = function () {
122
					ShareService.getPendingRequests().then(function (shareRequests) {
123
						if (shareRequests.length > 0) {
124
							$scope.incoming_share_requests = shareRequests;
125
							jQuery('.share_popup').dialog({
126
								width: 600,
127
								position: ['center', 90]
128
							});
129
						}
130
					});
131
				};
132
133
134
135
				var refresh_data_interval = null;
136
				if ($scope.active_vault) {
137
					$scope.$parent.selectedVault = true;
138
					fetchCredentials();
139
					getPendingShareRequests();
140
					refresh_data_interval = $interval(function () {
141
						fetchCredentials();
142
						getPendingShareRequests();
143
					}, 60000 * 5);
144
				}
145
				$scope.$on('$destroy', function () {
146
					$interval.cancel(refresh_data_interval);
147
				});
148
149
150
				$scope.permissions = new SharingACL(0);
151
152
				$scope.hasPermission = function (acl, permission) {
153
					if (acl) {
154
						var tmp = new SharingACL(acl.permission);
155
						return tmp.hasPermission(permission);
156
					} else {
157
						return true;
158
					}
159
160
				};
161
162
				$scope.acceptShareRequest = function (share_request) {
163
					var crypted_shared_key = share_request.shared_key;
164
					var private_key = EncryptService.decryptString(VaultService.getActiveVault().private_sharing_key);
165
166
					private_key = ShareService.rsaPrivateKeyFromPEM(private_key);
167
					/** global: forge */
168
					crypted_shared_key = private_key.decrypt(forge.util.decode64(crypted_shared_key));
169
					crypted_shared_key = EncryptService.encryptString(crypted_shared_key);
170
171
					ShareService.saveSharingRequest(share_request, crypted_shared_key).then(function () {
172
						var idx = $scope.incoming_share_requests.indexOf(share_request);
173
						$scope.incoming_share_requests.splice(idx, 1);
174
						var active_share_requests = false;
175
						for (var v = 0; v < $scope.incoming_share_requests.length; v++) {
176
							if ($scope.incoming_share_requests[v].target_vault_id === $scope.active_vault.vault_id) {
177
								active_share_requests = true;
178
							}
179
						}
180
						if (active_share_requests === false) {
181
							jQuery('.ui-dialog').remove();
182
							fetchCredentials();
183
						}
184
					});
185
				};
186
187
				$scope.declineShareRequest = function (share_request) {
188
					ShareService.declineSharingRequest(share_request).then(function () {
189
						var idx = $scope.incoming_share_requests.indexOf(share_request);
190
						$scope.incoming_share_requests.splice(idx, 1);
191
						var active_share_requests = false;
192
						for (var v = 0; v < $scope.incoming_share_requests.length; v++) {
193
							if ($scope.incoming_share_requests[v].target_vault_id === $scope.active_vault.vault_id) {
194
								active_share_requests = true;
195
							}
196
						}
197
						if (active_share_requests === false) {
198
							jQuery('.ui-dialog').remove();
199
							fetchCredentials();
200
						}
201
					});
202
				};
203
204
205
206
				var settingsLoaded = function () {
207
					$scope.settings = SettingsService.getSettings();
208
				};
209
210
				if(!SettingsService.getSetting('settings_loaded')){
211
					$rootScope.$on('settings_loaded', function () {
212
						settingsLoaded();
213
					});
214
				} else {
215
					settingsLoaded();
216
				}
217
218
219
				$scope.addCredential = function () {
220
					var new_credential = CredentialService.newCredential();
221
					var enc_c = CredentialService.encryptCredential(new_credential);
222
					SettingsService.setSetting('edit_credential', enc_c);
223
					$location.path('/vault/' + $scope.active_vault.guid + '/new');
224
				};
225
226
				$scope.editCredential = function (credential) {
227
					var _credential = angular.copy(credential);
228
					$rootScope.$emit('app_menu', false);
229
					SettingsService.setSetting('edit_credential', CredentialService.encryptCredential(_credential));
230
					$location.path('/vault/' + $scope.active_vault.guid + '/edit/' + _credential.guid);
231
				};
232
233
				$scope.getRevisions = function (credential) {
234
					var _credential = angular.copy(credential);
235
					$rootScope.$emit('app_menu', false);
236
					SettingsService.setSetting('revision_credential', CredentialService.encryptCredential(_credential));
237
					$location.path('/vault/' + $scope.active_vault.guid + '/' + _credential.guid + '/revisions');
238
				};
239
240
				$scope.shareCredential = function (credential) {
241
					var _credential = angular.copy(credential);
242
					$rootScope.$emit('app_menu', false);
243
					SettingsService.setSetting('share_credential', CredentialService.encryptCredential(_credential));
244
					$location.path('/vault/' + $scope.active_vault.guid + '/' + _credential.guid + '/share');
245
				};
246
247
				var notification;
248
				$scope.deleteCredential = function (credential) {
249
					var _credential = angular.copy(credential);
250
					try {
251
						_credential = CredentialService.decryptCredential(angular.copy(credential));
252
					} catch (e) {
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
253
254
					}
255
					_credential.delete_time = new Date().getTime() / 1000;
256
					for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
257
						if ($scope.active_vault.credentials[i].credential_id === credential.credential_id) {
258
							$scope.active_vault.credentials[i].delete_time = _credential.delete_time;
259
						}
260
					}
261
					$scope.closeSelected();
262
					if (notification) {
263
						NotificationService.hideNotification(notification);
264
					}
265
					notification = NotificationService.showNotification($translate.instant('credential.deleted'), 5000,
266
						function () {
267
							var key = CredentialService.getSharedKeyFromCredential(_credential);
268
							CredentialService.updateCredential(_credential, false, key).then(function (result) {
269
								if (result.delete_time > 0) {
270
									notification = false;
271
272
								}
273
							});
274
						});
275
276
				};
277
278
				$scope.recoverCredential = function (credential) {
279
					var _credential = angular.copy(credential);
280
					try {
281
						_credential = CredentialService.decryptCredential(angular.copy(credential));
282
					} catch (e) {
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
283
284
					}
285
					for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
286
						if ($scope.active_vault.credentials[i].credential_id === credential.credential_id) {
287
							$scope.active_vault.credentials[i].delete_time = 0;
288
						}
289
					}
290
					_credential.delete_time = 0;
291
					$scope.closeSelected();
292
					if (notification) {
293
						NotificationService.hideNotification(notification);
294
					}
295
					NotificationService.showNotification($translate.instant('credential.recovered'), 5000,
296
						function () {
297
							var key = CredentialService.getSharedKeyFromCredential(_credential);
298
							CredentialService.updateCredential(_credential, false, key).then(function () {
299
								notification = false;
300
301
							});
302
						});
303
304
				};
305
306
				$scope.destroyCredential = function (credential) {
307
					var _credential = angular.copy(credential);
308
					CredentialService.destroyCredential(_credential.guid).then(function () {
309
						for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
310
							if ($scope.active_vault.credentials[i].credential_id === credential.credential_id) {
311
								$scope.active_vault.credentials.splice(i, 1);
312
								NotificationService.showNotification($translate.instant('credential.destroyed'), 5000);
313
								break;
314
							}
315
						}
316
					});
317
				};
318
319
				$scope.view_mode = 'list'; //@TODO make this a setting
320
				$scope.switchViewMode = function (viewMode) {
321
					$scope.view_mode = viewMode;
322
				};
323
324
				$scope.filterOptions = {
325
					filterText: '',
326
					fields: ['label', 'username', 'email', 'custom_fields']
327
				};
328
329
330
				$scope.filtered_credentials = [];
331
				$scope.$watch('[selectedtags, filterOptions, delete_time, active_vault.credentials]', function () {
332
					if (!$scope.active_vault) {
333
						return;
334
					}
335
					if ($scope.active_vault.credentials) {
336
						var credentials = angular.copy($scope.active_vault.credentials);
337
						var filtered_credentials = $filter('credentialSearch')(credentials, $scope.filterOptions);
338
						filtered_credentials = $filter('tagFilter')(filtered_credentials, $scope.selectedtags);
339
						filtered_credentials = $filter('filter')(filtered_credentials, {hidden: 0});
340
						$scope.filtered_credentials = filtered_credentials;
341
						$scope.filterOptions.selectedtags = angular.copy($scope.selectedtags);
342
						for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
343
							var _credential = $scope.active_vault.credentials[i];
344
							if (_credential.tags) {
345
								TagService.addTags(_credential.tags);
346
							}
347
						}
348
					}
349
350
				}, true);
351
352
				$scope.selectedtags = [];
353
				var to;
354
				$rootScope.$on('selected_tags_updated', function (evt, _sTags) {
355
					var _selectedTags = [];
356
					for (var x = 0; x < _sTags.length; x++) {
357
						_selectedTags.push(_sTags[x].text);
358
					}
359
					$scope.selectedtags = _selectedTags;
360
					$timeout.cancel(to);
361
					if (_selectedTags.length > 0) {
362
						to = $timeout(function () {
363
							if ($scope.filtered_credentials) {
364
								var _filtered_tags = [];
365
								for (var i = 0; i < $scope.filtered_credentials.length; i++) {
366
									var tags = $scope.filtered_credentials[i].tags_raw;
367
									for (var x = 0; x < tags.length; x++) {
368
										var tag = tags[x].text;
369
										if (_filtered_tags.indexOf(tag) === -1) {
370
											_filtered_tags.push(tag);
371
										}
372
									}
373
								}
374
375
								$rootScope.$emit('limit_tags_in_list', _filtered_tags);
376
							}
377
						}, 50);
378
					}
379
				});
380
381
				$scope.delete_time = 0;
382
				$scope.showCredentialRow = function (credential) {
383
					if ($scope.delete_time === 0) {
384
						return credential.delete_time === 0;
385
					} else {
386
						return credential.delete_time > $scope.delete_time;
387
					}
388
389
				};
390
391
				$rootScope.$on('set_delete_time', function (event, time) {
392
					$scope.delete_time = time;
393
				});
394
395
				$scope.setDeleteTime = function (delete_time) {
396
					$scope.delete_time = delete_time;
397
				};
398
399
				$scope.selectedCredential = false;
400
				$scope.selectCredential = function (credential) {
401
					if(credential.description) {
402
						credential.description_html = $sce.trustAsHtml(angular.copy(credential.description).replace("\n", '<br />'));
403
					}
404
					$scope.selectedCredential = angular.copy(credential);
405
					$rootScope.$emit('app_menu', true);
406
				};
407
408
				$scope.closeSelected = function () {
409
					$rootScope.$emit('app_menu', false);
410
					$scope.selectedCredential = false;
411
				};
412
413
				$rootScope.$on('logout', function () {
414
					$scope.active_vault = null;
415
					$scope.credentials = [];
416
//				$scope.$parent.selectedVault = false;
417
418
				});
419
420
				$scope.clearState = function () {
421
					$scope.delete_time = 0;
422
				};
423
424
				$scope.downloadFile = function (credential, file) {
425
					var callback = function (result) {
426
						var key = EncryptService.getSharedKeyFromCredential(credential);
427
428
						if (!result.hasOwnProperty('file_data')) {
429
							NotificationService.showNotification($translate.instant('error.loading.file.perm'), 5000);
430
							return;
431
432
						}
433
						var file_data = EncryptService.decryptString(result.file_data, key);
434
						download(file_data, escapeHTML(file.filename), file.mimetype);
435
436
					};
437
438
					if (!credential.hasOwnProperty('acl')) {
439
						FileService.getFile(file).then(callback);
440
					} else {
441
						ShareService.downloadSharedFile(credential, file).then(callback);
442
					}
443
444
				};
445
446
			}]);
447
}());